﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace EverydayTips
{
    [Serializable]
    class Index
    {
        public Index()
        {
            Tiplist = new Hashtable();
            dateIndex = new Hashtable();
            keywordsIndex = new Hashtable();
        }
        public void indexItem(Guid uid,string title, string date,string keywords)
        {
            
            add2IDlist(uid,title);
            addDateIndex(date, uid);
            addKeywordsIndex(keywords, uid);
        }
        public void deleteItem(Guid uid, string date, string keywords)
        {
            deleteFromGUIDlist(uid);
            delDateIndex(date,uid);
            delKeywordsIndex(keywords,uid);
        }
        private void add2IDlist(Guid uid,string title)
        {
            Tiplist.Add(uid,title);
        }
        private void deleteFromGUIDlist(Guid uid)
        {
            Tiplist.Remove(uid);
        }
        private void addDateIndex(string date, Guid uid)
        {
            if (dateIndex.Contains(date))
            {
                ArrayList IDlist = (ArrayList)dateIndex[date];
                IDlist.Add(uid);
                dateIndex[date] = IDlist;
            }
            else
            {
                ArrayList IDlist = new ArrayList();
                IDlist.Add(uid);
                dateIndex.Add(date, IDlist);
            }
        }
        private void delDateIndex(string date, Guid uid)
        {
            if (dateIndex.Contains(date))
            {
                ArrayList IDlist = (ArrayList)dateIndex[date];
                IDlist.Remove(uid);
                dateIndex[date] = IDlist;
            }
        }
        public void addKeywordsIndex(string keywords, Guid uid)
        {
            string keywords_str = keywords.Trim();
            keywords_str = keywords_str.ToLower();
            string[] keyword_list = keywords_str.Split(new char[] { ' ' });
            for (int i = 0; i < keyword_list.Length; i++)
            {
                this.addKeywordIndex(keyword_list[i], uid);
            }
        }
        private void delKeywordsIndex(string keywords, Guid uid)
        {
            string keywords_str = keywords.Trim();
            string[] keyword_list = keywords_str.Split(new char[] { ' ' });
            for (int i = 0; i < keyword_list.Length; i++)
            {
                this.delKeywordIndex(keyword_list[i], uid);
            }
        }
        private void addKeywordIndex(string keyword, Guid uid)
        {
            if (keyword == "")
                return;
            if (keywordsIndex.Contains(keyword))
            {
                ((ArrayList)keywordsIndex[keyword]).Add(uid);
                //ArrayList IDlist = (ArrayList)keywordsIndex[keyword];
                //IDlist.Add(uid);
                //keywordsIndex[keyword] = IDlist;
            }
            else
            {
                ArrayList IDlist = new ArrayList();
                IDlist.Add(uid);
                keywordsIndex.Add(keyword,IDlist);
            }
        }
        private void delKeywordIndex(string keyword, Guid uid)
        {
            if (keyword == "")
                return;
            if (keywordsIndex.Contains(keyword))
            {
               // ArrayList IDlist =
                //Debug: 
               // Util.Log("Before deleting keyword: " + keyword);
               // Util.Log(Util.Array2String(keywordsIndex[keyword]));
                ((ArrayList)keywordsIndex[keyword]).Remove(uid);
               // Util.Log("After deleting keyword: " + keyword);
               // Util.Log(Util.Array2String(keywordsIndex[keyword]));
               // IDlist.Remove(uid);
               // keywordsIndex[keyword] = IDlist;
            }
        }
        public ArrayList getIDlist()
        {
            ICollection al = this.Tiplist.Keys;
            ArrayList ret = null;
            if (al != null)
            {
                ret = new ArrayList(al);
            }else
            {
                ret = new ArrayList();
            }
            return ret;
            
        }
        public ArrayList getIDlistByDate(string date)
        {
            ArrayList al =  (ArrayList)dateIndex[date];
            ArrayList ret = null;
            if (al != null)
            {
                ret = new ArrayList(al);
            }
            else
            {
                ret = new ArrayList();
            }
            return ret;
        }
        public ArrayList getIDlistByKeywords(string keywords)
        {
            string keywords_str = keywords.ToLower();
            ArrayList al = _getIDlistByKeywords(keywords_str);
            ArrayList ret = null;
            if (al != null)
            {
                ret = new ArrayList(al);
            }
            else
            {
                ret = new ArrayList();
            }
            return ret;
        }
        private ArrayList _getIDlistByKeywords(string keywords)
        {
            string keywords_str = keywords.Trim();
            string[] keyword_list = keywords_str.Split(new char[] { ' ' });
            ArrayList resultList = null;
            for (int i = 0; i < keyword_list.Length; i++)
            {
                if (i == 0)
                    resultList = (ArrayList)keywordsIndex[keyword_list[0]];
                else
                {
                    if (resultList != null)
                    {
                        ArrayList tmpList = (ArrayList)keywordsIndex[keyword_list[i]];
                        for (int j = 0; j < resultList.Count; j++)
                        {
                            if (!tmpList.Contains(resultList[j]))
                            {
                                resultList.RemoveAt(j);
                                j--;
                            }
                        }
                    }
                    else
                    {
                        return null;
                    }
                }
            }
            return resultList;
        }
        public static void save(Index index)
        {
            FileStream fs = new FileStream(@"data\index.etp", FileMode.Create);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(fs, index);
            fs.Close();
        }
        public static Index fetch()
        {
            Index index = null;
            FileStream fs = new FileStream(@"data\index.etp", FileMode.Open, FileAccess.Read, FileShare.Read);
            if (fs.Length == 0)
            {
                index = new Index();
            }
            else
            {
                BinaryFormatter bf = new BinaryFormatter();
                index = (Index)bf.Deserialize(fs);
            }
            fs.Close();
            return index;
        }
        public Hashtable Tiplist;
        public Hashtable dateIndex;
        public Hashtable keywordsIndex;
    }
}
